from django.shortcuts import render
from django.views import View
from meiduo_mall.utils.views import LoginRequiredMixinJSONMixin
from apps.orders.models import OrderInfo
from django import http
from apps.payment.models import Payment
from alipay import AliPay
from django.conf import settings

# Create your views here.


class PaymentView(LoginRequiredMixinJSONMixin, View):
    """支付宝支付"""
    def get(self, request, order_id):
        """对接支付宝支付功能"""
        # 校验参数:判断order_id是否存在
        try:
            # 要去支付的订单必须订单编号存在，而且必须是当前登录用户本人的订单，而且订单的状态必须是待支付
            order = OrderInfo.objects.get(order_id=order_id, user=request.user, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
        except OrderInfo.DoesNotExist:
            return http.JsonResponse({'code': 400, 'errmsg': '参数order_id错误'})

        # 对接支付宝接口
        # 创建AliPaySDK对象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,  # 应用ID,如果对接的是沙箱应用，那么就是沙箱应用的ID。反之，就是正式应用的ID
            app_notify_url=None,    # 默认异步回调URL;我们使用同步回调,所以传None
            app_private_key_string=open("apps/payment/keys/app_private_key.pem").read(),    # 应用私钥
            alipay_public_key_string=open("apps/payment/keys/alipay_public_key.pem").read(),    # 支付宝公钥
            sign_type='RSA2',   # 密钥签名算法标准
            debug=settings.ALIPAY_DEBUG,    # 调试模式
        )

        """
        如果是安装的最新的支付宝SDK，读取秘钥的方式是读取秘钥字符串
        app_private_key_string = open("/path/to/your/private/key.pem").read()
        alipay_public_key_string = open("/path/to/alipay/public/key.pem").read()

        app_private_key_string=app_private_key_string,
        alipay_public_key_string=alipay_public_key_string,
        """

        # 调用SDK提供的接口方法,获取收银台链接
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,  # 美多商城维护订单号
            total_amount=str(order.total_amount),    # 支付金额
            subject='美多商城%s' % order_id,    # 订单标题
            return_url=settings.ALIPAY_RETURN_URL,  # 支付完成后回调地址
        )

        # 使用网关拼接order_string获得收银台页面链接
        alipay_url = settings.ALIPAY_URL + '?' + order_string

        # 返回结果
        return http.JsonResponse({'code': 0, 'errmsg': 'OK', 'alipay_url': alipay_url})


class PaymentStatusView(LoginRequiredMixinJSONMixin, View):
    """保存订单支付结果"""
    def get(self, request):
        # 接收参数:接受所有查询字符串
        query_dict = request.GET    # request.GET返回的是Query_Dict,不是字典,没有pop方法,

        # 使用参数验证该回调是否是支付宝的回调
        # 将查询字符串参数转字典
        data_dict = query_dict.dict()
        # 剔除并接收查询字符串参数中的sign
        signature = data_dict.pop("sign")

        # 创建支付宝SDK对象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,    # 应用的ID，如果对接的是沙箱应用，那么就是沙箱应用的ID。反之，就是正式应用的ID
            app_notify_url=None,        # 默认回调url
            app_private_key_string=open("apps/payment/keys/app_private_key.pem").read(),
            alipay_public_key_string=open('apps/payment/keys/alipay_public_key.pem').read(),
            sign_type="RSA2",
            debug=settings.ALIPAY_DEBUG,
        )

        # 最后sign参数和其他查询字符串签名后的结果进行对比
        success = alipay.verify(data_dict, signature)
        # 使用支付宝SDK对象调用验证回调的接口方法
        if success:
            # 说明是支付宝返回的安全回调
            # 读取支付宝和美多商城维护的订单号,并且绑定到一起
            out_trade_no = data_dict.get('out_trade_no')
            trade_no = data_dict.get('trade_no')
            Payment.objects.create(
                order_id = out_trade_no,
                trade_id = trade_no,
            )

            # 验证通过
            # 读取支付宝订单编号和美多商城订单编号并绑定
            # 修改订单状态
            OrderInfo.objects.filter(order_id=out_trade_no, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']).update(status=OrderInfo.ORDER_STATUS_ENUM['UNCOMMENT'])

            # 响应支付成功页面
            return http.JsonResponse({'code': 0, 'errmsg': 'OK', 'trade_id': trade_no})
        else:
            # 验证失败,响应非法请求
            return http.JsonResponse({'code': 400, 'errmsg': '非法请求'})
